package com.mhfelipe.sandbox.rpx;

import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.api.json.JSONJAXBContext;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;

/**
 * Created by IntelliJ IDEA.
 * User: mhfelipe
 * Date: 2/13/12
 * Time: 3:12 PM
 * To change this template use File | Settings | File Templates.
 */
public class RpxFilter implements Filter {

    private static final String baseUrl = "/";

    private static final String apiKey = "83113ba76a0966d7ce4f36d572504d426752d126";

    private static final String RPX_URL = "https://rpxnow.com/api/v2/auth_info";

    private HttpClient httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        HttpSession sessao = req.getSession();

        Identity identity = (Identity) sessao.getAttribute(Identity.SESSION_ID);

        if (identity == null) {
            String token = request.getParameter("token");
            if (token == null) {
                request.getRequestDispatcher(baseUrl).forward(req, resp);
            } else {
                PostMethod postMethod = new PostMethod(RPX_URL);
                postMethod.addParameter("token", token);
                postMethod.addParameter("apiKey", apiKey);
                postMethod.addParameter("format", "xml");

                int status = httpClient.executeMethod(postMethod);
                if (status == 200) {

                    InputStream inputStream = postMethod.getResponseBodyAsStream();

                    identity = getCredencial(inputStream);
                    if (identity == null) {
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
                    } else {
                        request.setAttribute(Identity.SESSION_ID, identity);
                        chain.doFilter(req, resp);
                    }
                }
            }
        } else {
            chain.doFilter(req, resp);
        }

    }

    public Identity getCredencial(InputStream in) throws IOException {

        try {
            JSONJAXBContext context = new JSONJAXBContext(JSONConfiguration.natural().build(), Identity.class);
            return context.createJSONUnmarshaller().unmarshalFromJSON(in, Identity.class);
        } catch (Exception e) {
            throw new IllegalArgumentException("Nao conseguiu fazer o parse", e);
        }
    }

    @Override
    public void destroy() {
    }

}
